package weeny.pre.face.treetable;

import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

import prefuse.data.Node;
import prefuse.data.Table;
import prefuse.data.Tree;
import prefuse.data.expression.Predicate;
import prefuse.data.parser.DataParser;
import prefuse.data.parser.ObjectParser;
import prefuse.util.io.IOLib;
import prefuse.visual.VisualTupleSet;

/**
 * Provide a model for {@link Tree}
 * @author weeny
 *
 */
public class PreTreeModel extends AbstractPreModel{
	 
	private Tree preTree = null;
	public PreTreeModel(Tree tree, String...columns) {
		super(new PreTreeNode(columns[0], tree.getRoot()), columns);
		preTree = tree;
	}
	
	public void setValueAt(Object aValue, Object node, int column) {
		super.setValueAt(aValue, node, column);
		if (preTree instanceof VisualTupleSet) {
			((VisualTupleSet)preTree).getVisualization().repaint();
		}
	}
	
	protected List<String> getColumnNameCandidates() {
		List<String> names = new ArrayList<String>();
		for(int i = 0; i<preTree.getNodeTable().getColumnCount(); i++){
			names.add(preTree.getNodeTable().getColumnName(i));
		}
		return names;
	}
	
	protected List<Table> getTableList() {
		List<Table> result = new ArrayList<Table>();
		result.add(preTree.getNodeTable());
		return result;
	}

	protected void setFilter(Predicate filter) {
		throw new UnsupportedOperationException();
	}
}

//helper class
class PreTreeNode extends AbstractTreeNode{
	public static ImageIcon parentIcon = new ImageIcon(
			IOLib.urlFromString("tree.gif", PreTreeNode.class, false));
	public static ImageIcon leafIcon = new ImageIcon(
			IOLib.urlFromString("leaf.gif", PreTreeNode.class, false));
	@Override
	public void setTreeIcon(JLabel label, boolean expanded) {
		if (getChildCount() == 0) {
			label.setIcon(leafIcon);
		}
		else {
			label.setIcon(parentIcon);
		}
	}
	public PreTreeNode(String label, Node obj) {
		super(label, label, obj);
	}
	public String toString() {
		return ((Node)obj).getString(str);
	}
	public int getChildCount() {
		return ((Node)obj).getChildCount();
	}
	public AbstractTreeNode getChild(int idx) {
		return new PreTreeNode(str,((Node)obj).getChild(idx));
	}
	public boolean isCelleEditable(String field) {
		return !(getParser(field) instanceof ObjectParser);
	}
	public Object toView(String field) {
		return toView(getParser(field), ((Node)obj).get(field));
	}
	public boolean toData(Object view, String field){
		return toData((Node)obj, view, field);
	}
	public Class getType(String field) {
		return getParser(field).getType();
	}
	//get the parser for this field
	private DataParser getParser(String field) {
		return ((Node)obj).getTable().getColumn(field).getParser();
	}
}
